/**
	authoer:yeqin
	github:
	QQ:892280082@qq.com
*/
const {SHELL_ASYNC} = require('./src/commonLib')
const {CompileFile} = require('./src/CompileFile')
const {convertPlaceHolder,getConfigFile,compileJsFile,convertTestForClsp} = require('./src/PlaceHolderReplace.js')
const path = require('path')


//python库位置
const pythonlib = path.join(__dirname,"pythonLib")
const clspLib = path.join(__dirname,"clspLib")

//基础库文件
const libFile = path.join(__dirname,"snapshot","defineCommonLib.js")
//定义的类文件
const defineCommonClass = path.join(__dirname,"snapshot","defineCommonClass.js")
//定义的通用函数文件
const clspFnFile = path.join(__dirname,"snapshot","defineCommonFunction.js")
//定义的python库文件
const pythonlibFile = path.join(__dirname,"snapshot","definePythonLib.js")
const clspLibFile = path.join(__dirname,"snapshot","defineClspLib.js")
const testOperateFile = path.join(__dirname,"snapshot","defineOperate.js")

const stringify = JSON.stringify

//编译@指令
const compileInstruct = compileFile => {
	const userScope = getConfigFile(compileFile.getFileDir(),"preclsp.json",5)
	const scope = {
		"@FileName":stringify(compileFile.getFileName())
	}
	convertPlaceHolder(compileFile,{...scope,...userScope})
}

//设置常量
const setConstant = (operateFile,bindFile,logFile)=>{
	return `const LOG_FILE = ${stringify(logFile.fsPath)}; \n`+
	`let XCH_ADDRESS_PREFIX = 'txch'; \n`+
	`const JS_FILE = ${stringify(bindFile.fsPath)}; \n`+
	`const FileName = ${stringify(operateFile.getFileName())}; \n`+
	`const WORK_DIR = ${stringify(operateFile.getFileDir())}; \n`+
	`let DEBUG_FLAG = false; \n`+
	`const TEMP_FILES = [${stringify(logFile.fsPath)},${stringify(bindFile.fsPath)}]; \n`+
	`const __DIRNAME = __dirname; \n`+
	`let __isDeploy__ = 0;`+
	`const PYTHON_LIB = ${stringify(pythonlib)}; \n`+
	`const CLSP_LIB = ${stringify(clspLib)}; \n`
}


//设置结束事件
const addOverEvent = ()=>{
	return `OVER_EVENT()`;
}

/**
@desc 向编译执行文件bindFile 写入数据
@param operateFile:CompileFile 当前操作的文件
@param bindFile:CompileFile 目标执行文件
@param logFile:CompileFile 日志文件
@param fn:bindFile=>{}  回调函数
*/
const generateRunFile = (operateFile,bindFile,logFile,fn)=>{

	bindFile.appendFile(libFile)
		.append(setConstant(operateFile,bindFile,logFile))
		.appendJsFile(CompileFile.of(clspFnFile))
		.appendJsFile(CompileFile.of(defineCommonClass))
		.appendJsFile(CompileFile.of(clspLibFile))
		.appendJsFile(CompileFile.of(pythonlibFile))
		.appendJsFile(CompileFile.of(testOperateFile));
	
	fn(bindFile)

	bindFile.writeFile();
}


//编译带有脚本的clsp文件
exports.compileClsp = async compileFile => {

	//分隔符
	const SPLIT_FLAG = "(mod";

	const operateFile = CompileFile.of(compileFile);

	const operateFileName = operateFile.getFileName(true)

	if(operateFile.content.indexOf(SPLIT_FLAG) == -1){
		ERROR(`not find [${SPLIT_FLAG}] band`)
		return;
	}

	convertTestForClsp(operateFile)

	compileInstruct(operateFile);


	const bindFile = operateFile.createFileInCurrentDir(`${operateFileName}_runtime.js`)

	const logFile = operateFile.createFileInCurrentDir(`${operateFileName}_runtime.clspLog`)

	const compileContent = operateFile.content.split(SPLIT_FLAG)

	generateRunFile(operateFile,bindFile,logFile,f => {

		f.appendAsyncWrapStar()
		.append(compileContent[0].replace(/\n;/g,"\n"))
		.append(addOverEvent())
		.appendAsyncWrapEnd()

	})

	await SHELL_ASYNC('node',[`${bindFile.getFileName()}`])
}

//编译 #！clsp 开头的js文件
exports.compileJs = async (jsCompileFile)=>{

	const BASH_FLAG = "#!clsp"

	const operateFile = CompileFile.of(jsCompileFile)

	const operateFileName = operateFile.getFileName(true)

	if(operateFile.content.indexOf(BASH_FLAG) == 0){

		operateFile.replace(BASH_FLAG,"")

		compileInstruct(operateFile);

		const bindFile = operateFile.createFileInCurrentDir(`${operateFileName}_runtime.js`)

		const logFile = operateFile.createFileInCurrentDir(`${operateFileName}_runtime.clspLog`)



		generateRunFile(operateFile,bindFile,logFile,f => {

			f.appendAsyncWrapStar()
			.appendJsFile(operateFile)
			.append(addOverEvent())
			.appendAsyncWrapEnd()

		})

		const binFile = path.join(operateFile.getFileDir(),bindFile.getFileName());


		await SHELL_ASYNC('node',[`${ binFile }`])
		
	}else{
		await SHELL_ASYNC('node',[`${jsCompileFile}`])
	}

}

